fn main() {
  //1. 变量定义, 类型可以自动推导
  let a = 1; //← 可以发现类型可以自动推导 编辑器已经提示除了 该变量为i32
  println!("{}", a); //1
  // let b: u32 = 1;
  // println!("{}", b);

  //1.2 可以后赋值
  let c;
  c = 123;
  println!("{}", c); //123

  //1.3 没有声明提升
  // println!("{}", d); //error[E0425]: cannot find value `d` in this scope
  // let d = 333;

  /** 不可变性*/
  //2. 默认变量是不可变的
  // a = 234; //Cannot assign twice to immutable variable [E0384]

  //3. mut ---> mutable 关键字 能让其变成可变变量
  // println!("{}", b); //error[E0425]: cannot find value `b` in this scope
  let mut b: u32 = 1;
  b = 234;
  println!("{}", b); //234

  /** 隐藏性, 后面的同名的变量 把 前面同名的变量 给隐藏了
      emmm, 就是可以重复定义
      隐藏？覆盖？  覆盖是用新的覆盖旧的，旧的消失了 (内存上来说)
   */
  //4. ↓重复定义 允许不同的类型 并且没有报错, 因为它只是 恰巧与第一个变量同名的崭新变量
  let b: f32 = 1.1;
  println!("{}", b); //1.1

  //5. 常量
  // ↓ 常量会声明提升
  println!("{}", MAX_POINT); //100000
  const MAX_POINT: u32 = 100000;
  println!("{}", MAX_POINT); //100000

  /** 常量 和 不可变变量 的区别
      首先, 不允许对常量使用 mut。常量不光默认不能变，它总是不能变（即无法重复声明）。
      其次, 常量是在编译期间进行求值的, 而不可变变量通常是在运行期间进行求值的
      最后, rust里 const常量有声明提升, 但let变量没有
   */
  const A_CONST:i32 = 1+2+3; //表达式会在编译期期间求值
  // const A_CONST:i32 = 1+2+3; //报错: A value named `A_CONST` has already been defined in this block [E0428]


  // const A_CONST2:i32 = get_number();
  fn get_number()->i32 {
    11
  } // ← 函数是在运行时进行的计算
  //↑ 运行会报错: error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
  // 但 可以赋给 let
  let d = get_number();
  println!("{}", d); //11
}
